import { expect } from '@jest/globals';
import fse from "fs-extra";
import path from 'path';

import { runHvigorAsync} from '../../common/common';
import { addOhPackageDps, commonJson5Operation } from '../../plugins/common-fun';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API11,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility
  },
  modulesOption: [ModuleTemplateType.StaticLibrary],
};

/**
 * 1、创建stage工程，添加staticLibrary模块
 * 2、entry依赖staticLibrary
 * 3、staticLibrary模块中build-profile.json5配置runtimeOnly
 * 4、构建hap
 * 5、查看entry/build/default/intermediates/loader.json中compileEntry是否有对应的buildOption
 * 6、修改har目录名后clean，再构建hap
 * 7、重复步骤5
 *
 * @param {Project} project
 * @param {TestTaskOption} taskConfig
 * @param {ICaseRecord} record
 * @return res
 */
const testfun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRoot = project.projectRootPath();
  const entryRootPath = project.getModule('entry').moduleRootPath();
  const harRootPath = project.getModule('staticLibrary').moduleRootPath();
  const loaderPath = path.resolve(entryRootPath, 'build/default/intermediates/loader/default/loader.json');
  const runtimePath = path.resolve(harRootPath, 'src/main/ets/components/mainpage/MainPage.ets');
  // entry依赖staticLibrary
  await addOhPackageDps(entryRootPath, { 'staticLibrary': 'file:../staticLibrary' });

  // staticLibrary中配置runtimeOnly
  await commonJson5Operation(path.resolve(harRootPath, 'build-profile.json5'), async (json5: any) => {
    json5.buildOption = {
      "arkOptions": {
        "runtimeOnly": {
          "sources": ["./src/main/ets/components/mainpage/MainPage.ets"]
        }
      }
    };
  });

  // 构建hap
  const commands = "--mode module -p product=default assembleHap".split(' ');
  const result1 = await runHvigorAsync(projectRoot, commands);
  record.addStep('第一次构建hap，检查compileEntry', result1);
  expect(result1.stdout).toContain('BUILD SUCCESSFUL');
  expect(fse.existsSync(loaderPath)).toEqual(true);

  const loaderPathStr = fse.readFileSync(loaderPath).toString();
  const runTimePathStr = runtimePath.replace(/\\/g, "\\\\");
  expect(loaderPathStr.includes(runTimePathStr)).toBe(true);

  // clean
  await runHvigorAsync(projectRoot, "-p product=default clean".split(' '));
  // 修改目录名
  await fse.rename(harRootPath, harRootPath.replace('staticLibrary', 'hhh'));
  await commonJson5Operation(path.resolve(projectRoot, 'build-profile.json5'), async (json5: any) => {
    json5.modules = [
      {
        "name": "entry",
        "srcPath": "./entry",
        "targets": [
          {
            "name": "default",
            "applyToProducts": [
              "default"
            ]
          }
        ]
      },
      {
        "name": "staticLibrary",
        "srcPath": "./hhh"
      }
    ]
  });
  await addOhPackageDps(entryRootPath, { 'staticLibrary': 'file:../hhh' });
  // 同步一下
  await runHvigorAsync(projectRoot, "--sync -p product=default".split(' '));

  // 再次构建hap
  const result2 = await runHvigorAsync(projectRoot, commands);
  record.addStep('改名后构建hap，检查compileEntry', result2);
  expect(result2.stdout).toContain('BUILD SUCCESSFUL');
  expect(fse.existsSync(loaderPath)).toEqual(true);
  expect(loaderPathStr.includes(runTimePathStr)).toBe(true);
};

TestCaseBuilder.builder()
  .caseName('DTS2024110571029')
  .description('手动修改模块目录，工程运行时buildOption丢失问题')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.DTS).build())
  .testFun(testfun)
  .load();
